window.mysql = window.mysql || {};
(function (ms, dbCfg) {
    dbCfg = dbCfg || {
        host: '127.0.0.1',
        user: 'root',
        password: 'mysql',
        database: 'jxc'
    };

    var req = window.require || window.top.require;
    var mysql = req('mysql');

    //ms.execute =  invoke;
    ms.doSql = doSql;

    ms.pageBysql = function (cfg) {

        prepareArguments(cfg);

        if (!cfg.page) {
            cfg.fail({"message": "分页参数不能为空！", success: false});
        }

        cfg.page.index = cfg.page.index || 1;
        cfg.page.index = cfg.page.index < 1 ? 1 : cfg.page.index;

        cfg.page.size = cfg.page.size || 20;
        cfg.page.size = cfg.page.size < 1 ? 20 : cfg.page.size;


        var countSql = "select count(*) from ( " + cfg.sql + " ) aaaaa";
        var pageSql = cfg.sql + " LIMIT " + ((cfg.page.index - 1) * cfg.page.size) + "," + cfg.page.size;


        /* var jsonData = {
            "total": Math.ceil(allData().length / size),//总页数
            "page": page,//页码
            "records": allData().length,//总记录数
            "rows": allData().slice((page - 1) * size, page * size)//当前页的数据
        }; */
        var result = {
            "records": 0,
            "page": cfg.page.index,
            "total": 0,
            "rows": []
        };

        var conn = mysql.createConnection(dbCfg);
        conn.connect();
        conn.query({sql: countSql, timeout: cfg.timeout}, cfg.data, function (err, res, fs) {
            if (err) {
                releaseConnection(conn);
                cfg.fail(err);
                return;
            } else {
                result.records = res[0]["count(*)"];
                result.total = Number.parseInt(result.records / cfg.page.size) + (result.records % cfg.page.size == 0 ? 0 : 1);

                conn.query({sql: pageSql, timeout: cfg.timeout}, cfg.data, function (err, res, fs) {
                    if (err) {
                        releaseConnection(conn);
                        cfg.fail(err);
                        return;
                    } else {
                        result.rows = res;
                        releaseConnection(conn);
                        cfg.success(result);
                    }

                });


            }
        });
    };

    ms.selectBysql = function (sql, args, successCallback, failCallback) {
        doSql({
            "sql": sql,
            "data": args,
            "success": successCallback,
            "fail": failCallback
        });
    };

    ms.insertBysql = function (sql, args, successCallback, failCallback) {
        if (sql.trim().toLowerCase().indexOf("insert") == -1) {
            sql = "INSERT INTO " + sql + " SET ?";
        }
        ms.selectBysql(sql, args, successCallback, failCallback);
    };

    ms.updateBysql = ms.selectBysql;
    ms.sql = ms.selectBysql;

    ms.insertBatch = function (tbl, datas, successCallback, failCallback) {
        //datas = datas || [];
        var cdatas = datas ? datas.slice(0) : [];
        successCallback = successCallback || function () {
        };
        failCallback = failCallback || function () {
        };


        var sql = "INSERT INTO " + tbl + " SET ?";
        var conn = mysql.createConnection(dbCfg);
        conn.connect();
        conn.beginTransaction(function (err) {
            if (err) {
                releaseConnection(conn);
                throw err;
            }
            var res = [];
            doSqlRecursion(conn, sql, cdatas, successCallback, failCallback, res);
        });
    };

    ms.sqlBatch = function (sql, datas, successCallback, failCallback) {
        //datas = datas || [];
        var cdatas = datas ? datas.slice(0) : [];
        successCallback = successCallback || function () {
        };
        failCallback = failCallback || function () {
        };

        var conn = mysql.createConnection(dbCfg);
        conn.connect();
        conn.beginTransaction(function (err) {
            if (err) {
                releaseConnection(conn);
                throw err;
            }
            var res = [];
            doSqlRecursion(conn, sql, cdatas, successCallback, failCallback, res);
        });
    };

    //递归执行
    function doSqlRecursion(conn, sql, ds, successCallback, failCallback, ress) {
        if (ds.length == 0) {
            conn.commit(function (err) {
                if (err) {
                    conn.rollback(function () {
                        releaseConnection(conn);
                        failCallback(err);
                    });
                }
                releaseConnection(conn);
                successCallback(ress);
            });
        } else {
            var dd = ds.pop();

            conn.query({sql: sql}, dd, function (err, res, fs) {
                if (err) {
                    conn.rollback(function () {
                        releaseConnection(conn);
                        failCallback(err);
                    });
                } else {
                    ress.push(res);
                    doSqlRecursion(conn, sql, ds, successCallback, failCallback, ress);
                }

            });
        }

    }

    function doSql(cfg) {
        var res = prepareArguments(cfg);
        if (!res.success) {
            cfg.fail(res);
            return;
        }

        invoke(function (conn) {
            conn.beginTransaction(function (err) {
                if (err) {
                    releaseConnection(conn);
                    throw err;
                }

                conn.query({sql: cfg.sql, timeout: cfg.timeout}, cfg.data, function (err, res, fs) {
                    if (err) {
                        return conn.rollback(function () {
                            releaseConnection(conn);
                            cfg.fail(err);
                        });
                    } else {

                        conn.commit(function (err) {
                            if (err) {
                                return conn.rollback(function () {
                                    releaseConnection(conn);
                                    cfg.fail(err);
                                });
                            }
                            releaseConnection(conn);
                            cfg.success(res, fs);
                        });
                    }
                });

            });
        });
    }

    function prepareArguments(cfg) {
        if (!cfg) return {"message": "传入参数不能为空！", success: false};
        if (!cfg.sql) return {"message": "必须传入sql ", success: false};

        cfg.timeout = cfg.timeout || 5000;// 10 seconds
        cfg.timeout = cfg.timeout <= 0 ? 5000 : cfg.timeout;

        cfg.data = cfg.data || [];
        cfg.success = cfg.success || function (d) {
        };
        cfg.fail = cfg.fail || function (d) {
            alert(d.message);
        };

        return {success: true};
    }

    function invoke(callback) {
        var conn = mysql.createConnection(dbCfg);
        conn.connect();
        callback(conn);
    }

    function releaseConnection(conn) {
        try {
            conn.end();
        } catch (error) {
        } finally {

        }
    }

})(window.mysql);

window.db = window.mysql;
